package cn.yhr.summerboot.context;

import cn.yhr.summerboot.context.annon.Auto;
import cn.yhr.summerboot.context.annon.Ioc;
import cn.yhr.summerboot.context.exception.IocException;
import cn.yhr.summerboot.core.util.StringCaseUtil;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;

/**
 * @Tittle AutowiredAnnotationProcessor
 * @Description
 * @Author yhr
 * @Date 2018/11/27 10:11
 * @Version 1.0
 */
public class AutowiredAnnotationProcessor {
    private IocApplication ioc=IocApplication.getApplication();

    public void findAutoAnnoInClasses(){
        //得到Ioc容器
        Collection<Object> applications = ioc.getApplications();
        //得到迭代器
        Iterator<Object> iterator = applications.iterator();
        while (iterator.hasNext()){
            //得到每个bean
            Object application = iterator.next();
            Class<?> clazz = application.getClass();
            //得到对象类的所有属性
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                //得到属性的注解
                Auto annotation = field.getAnnotation(Auto.class);
                //判断这个属性是否加了auto注解的
                if (annotation != null && annotation.required()) {
                    //按接口实现类--注入实现类
                    if(injectAutoAttriByInterface(field,application)) continue;

                    //按beanId注入实现类
                    if(injectAutoAttriByBeanId(field,application)) continue;
                }
            }
        }
    }

    /**
     * 给bean按接口实现类注入实现类
     * @param field 成员变量
     * @param application 实例对象
     * @return
     */
    private boolean injectAutoAttriByInterface(Field field,Object application) {
        //属性的接口类
        Class<?> clazz = field.getType();
        //找到属性的实现类
        Collection<Object> applications = ioc.getApplications();
        Iterator<Object> iterator = applications.iterator();
        while (iterator.hasNext()){
            //循环的每个Bean
            Object obj = iterator.next();
            Class<?>[] interfaces = obj.getClass().getInterfaces();
            for (Class<?> anInterface : interfaces) {
                // anInterface:循环的每个Bean的接口 情况适用于service 和serviceImpl
                if(clazz==anInterface){
                    return setFiledAttri(field,application,obj);
                }
            }
        }
        return false;
    }

    /**
     * 给bean按beanId注入实现类
     * @param field 成员变量
     * @param application 实例对象
     * @return
     */
    private boolean injectAutoAttriByBeanId(Field field,Object application){
        //字段的类型
        Class<?> clazz = field.getType();
        Ioc iocAnnon = clazz.getAnnotation(Ioc.class);
        if(iocAnnon==null){
            return false;
        }
        if(!StringUtils.isEmpty(iocAnnon.value())){
            //用户自定义BeanId
            return setFiledAttri(field, application, ioc.get(iocAnnon.value()));
        }
        Object o = ioc.get(StringCaseUtil.lowerFirst(clazz.getSimpleName()));
        if(o!=null){
            return setFiledAttri(field, application, o);
        }
        return false;
    }

    /**
     * 设置单个字段得属性
     * @param field 单个字段的对象
     * @param application 对象
     * @param o 单个字段对象的属性
     * @return
     */
    private boolean setFiledAttri(Field field, Object application, Object o) {
        try {
            field.setAccessible(true);
            field.set(application,o);
            return true;
        } catch (IllegalAccessException e) {
            //e.printStackTrace();
            throw new IocException("自动注入属性失败!");
        }
    }
}
